#ifndef _FEATURE3D_H_
#define _FEATURE3D_H_

#include "picture.h"

/* definition of a 3D point consist of x,y,z and rgb */
struct Point3D
{
  Point3D() {
    x = y = z = 0.0;
    r = g = b = 0;
  }

  Point3D(float x_, float y_, float z_) :x(x_), y(y_), z(z_) {
    r = g = b = 0;
  }

  Point3D(float x_, float y_, float z_,
    unsigned char r_, unsigned char g_, unsigned char b_)
    :x(x_), y(y_), z(z_), r(r_), g(g_), b(b_) {}

  Point3D(const Point3D& point) {
    x = point.x; y = point.y; z = point.z;
    r = point.r; g = point.g; b = point.b;
  }

  Point3D& operator=(const Point3D& point) {
    x = point.x; y = point.y; z = point.z;
    r = point.r; g = point.g; b = point.b;
    return (*this);
  }

  void Set3DCoordinate(float x_, float y_, float z_) {
    x = x_; y = y_; z = z_;
  }

  void Set3DPointColor(unsigned char r_, unsigned char g_, unsigned char b_) {
    r = r_; g = g_; b = b_;
  }

  float x, y, z;//coordinates
  unsigned char r, g, b;//point colors
};


/*  a View of a 3D point as defined by Bundler
contain the index of the camera the point was seen in it
the key point index in the .key file of that that camera
the x and y coordinate of that key point in a reference frame
the coordinate center is the center of the image
scale and orientation of that key point
*/
struct View
{
  size_t camera;  // the index of camera the feature was detected in
  size_t key;  // index of this feature

  KeyPoint keypt;

  View() :keypt(.0f, .0f, .0f, .0f) {
    camera = key = 0;
  }
};


/* store all the information of a 3D point,include a View list
The descriptor for View View_list[i] is stored in descriptors[128*i]...descriptors[128*i+127]
*/
struct Feature3DInfo
{
  Point3D mPoint;
  std::vector<View> mView_list;
  //each single descriptor save as unsigned char*
  std::vector<Descriptor> mDescriptors;

  //constructor
  Feature3DInfo() {
    mView_list.clear();
    mDescriptors.clear();
  }

  //destructor
  ~Feature3DInfo() {
    ClearData();
  }

  // copy all descriptor data to memory start at dst
  unsigned char* CopyDescData(unsigned char* dst) const;

  //clear all the data
  void ClearData() {
    mDescriptors.clear();
    mView_list.clear();
  }

  void ClearDesc() {
    mDescriptors.clear();
  }

  void ClearViewList() {
    mView_list.clear();
  }
};

#endif
